package com.cyy.daijia.driver.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSON;
import com.cyy.daijia.common.constant.SystemConstant;
import com.cyy.daijia.common.execption.CException;
import com.cyy.daijia.common.result.ResultCodeEnum;
import com.cyy.daijia.common.util.LocationUtil;
import com.cyy.daijia.dispatch.client.NewOrderFeignClient;
import com.cyy.daijia.driver.service.OrderService;
import com.cyy.daijia.map.client.LocationFeignClient;
import com.cyy.daijia.map.client.MapFeignClient;
import com.cyy.daijia.model.entity.order.OrderInfo;
import com.cyy.daijia.model.form.map.CalculateDrivingLineForm;
import com.cyy.daijia.model.form.order.OrderFeeForm;
import com.cyy.daijia.model.form.order.StartDriveForm;
import com.cyy.daijia.model.form.order.UpdateOrderBillForm;
import com.cyy.daijia.model.form.order.UpdateOrderCartForm;
import com.cyy.daijia.model.form.rules.FeeRuleRequestForm;
import com.cyy.daijia.model.form.rules.ProfitsharingRuleRequestForm;
import com.cyy.daijia.model.form.rules.RewardRuleRequestForm;
import com.cyy.daijia.model.vo.base.PageVo;
import com.cyy.daijia.model.vo.map.DrivingLineVo;
import com.cyy.daijia.model.vo.map.OrderLocationVo;
import com.cyy.daijia.model.vo.order.*;
import com.cyy.daijia.model.vo.rules.FeeRuleResponseVo;
import com.cyy.daijia.model.vo.rules.ProfitsharingRuleResponseVo;
import com.cyy.daijia.model.vo.rules.RewardRuleResponseVo;
import com.cyy.daijia.order.client.OrderInfoFeignClient;
import com.cyy.daijia.rules.client.FeeRuleFeignClient;
import com.cyy.daijia.rules.client.ProfitsharingRuleFeignClient;
import com.cyy.daijia.rules.client.RewardRuleFeignClient;
import com.cyy.daijia.model.vo.order.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {
    private final OrderInfoFeignClient orderInfoFeignClient;
    private final NewOrderFeignClient newOrderFeignClient;
    private final MapFeignClient mapFeignClient;
    private final LocationFeignClient locationFeignClient;
    private final FeeRuleFeignClient feeRuleFeignClient;
    private final RewardRuleFeignClient rewardRuleFeignClient;
    private final ProfitsharingRuleFeignClient profitsharingRuleFeignClient;

    @Override
    public Integer getOrderStatus(Long orderId) {
        return orderInfoFeignClient.getOrderStatus(orderId).getData();
    }

    @Override
    public List<NewOrderDataVo> findNewOrderQueueData(Long driverId) {
        return newOrderFeignClient.findNewOrderQueueData(driverId).getData();
    }

    @Override
    public Boolean robNewOrder(Long driverId, Long orderId) {
        return orderInfoFeignClient.robNewOrder(driverId, orderId).getData();
    }

    @Override
    public CurrentOrderInfoVo searchDriverCurrentOrder(Long driverId) {
        return orderInfoFeignClient.searchDriverCurrentOrder(driverId).getData();
    }

    @Override
    public OrderInfoVo getOrderInfo(Long orderId, Long driverId) {
        OrderInfo orderInfo = orderInfoFeignClient.getOrderInfo(orderId).getData();
        if(orderInfo.getDriverId()==driverId){
            OrderInfoVo orderInfoVo = BeanUtil.copyProperties(orderInfo, OrderInfoVo.class);
            orderInfoVo.setOrderId(orderInfo.getId());

            OrderBillVo orderBillVo = null;

            OrderProfitsharingVo orderProfitsharing = null;
            //账单结束才有这些信息
            if(orderInfo.getStatus()>=6){
                orderBillVo = orderInfoFeignClient.getOrderBillInfo(orderId).getData();
                orderProfitsharing = orderInfoFeignClient.getOrderProfitsharing(orderId).getData();
            }
            orderInfoVo.setOrderBillVo(orderBillVo);
            orderInfoVo.setOrderProfitsharingVo(orderProfitsharing);

            return orderInfoVo;

        }
        throw new CException(ResultCodeEnum.ILLEGAL_REQUEST);
    }

    @Override
    public DrivingLineVo calculateDrivingLine(CalculateDrivingLineForm calculateDrivingLineForm) {
        return mapFeignClient.calculateDrivingLine(calculateDrivingLineForm).getData();
    }

    @Override
    public Boolean driverArriveStartLocation(Long orderId, Long driverId) {
        //防止刷单，计算司机的经纬度与代驾的起始经纬度是否在1公里范围内
        OrderInfo orderInfo = orderInfoFeignClient.getOrderInfo(orderId).getData();
        OrderLocationVo orderLocationVo = locationFeignClient.getCacheOrderLocation(orderId).getData();
        //司机的位置与代驾起始点位置的距离
        double distance = LocationUtil.getDistance(orderInfo.getStartPointLatitude().doubleValue(), orderInfo.getStartPointLongitude().doubleValue(), orderLocationVo.getLatitude().doubleValue(), orderLocationVo.getLongitude().doubleValue());
        if(distance > SystemConstant.DRIVER_START_LOCATION_DISTION) {
            throw new CException(ResultCodeEnum.DRIVER_START_LOCATION_DISTION_ERROR);
        }
        return orderInfoFeignClient.driverArriveStartLocation(orderId, driverId).getData();
    }

    @Override
    public Boolean updateOrderCart(UpdateOrderCartForm updateOrderCartForm) {
        return orderInfoFeignClient.updateOrderCart(updateOrderCartForm).getData();
    }
    @Override
    public Boolean startDrive(StartDriveForm startDriveForm) {
        return orderInfoFeignClient.startDrive(startDriveForm).getData();
    }

    @Override
    public Boolean endDrive(OrderFeeForm orderFeeForm) {
        //根据订单id判断是否是司机接单
        OrderInfo orderInfo = orderInfoFeignClient.getOrderInfo(orderFeeForm.getOrderId()).getData();
        if(orderInfo.getDriverId()!=orderFeeForm.getDriverId()){
            throw new CException(ResultCodeEnum.ILLEGAL_REQUEST);
        }


     /*   OrderServiceLastLocationVo orderServiceLastLocationVo = locationFeignClient.getOrderServiceLastLocation(orderFeeForm.getOrderId()).getData();
        //司机的位置与代驾终点位置的距离
        double distance = LocationUtil.getDistance(orderInfo.getEndPointLatitude().doubleValue(), orderInfo.getEndPointLongitude().doubleValue(), orderServiceLastLocationVo.getLatitude().doubleValue(), orderServiceLastLocationVo.getLongitude().doubleValue());
        if(distance > SystemConstant.DRIVER_START_LOCATION_DISTION) {
            throw new CException(ResultCodeEnum.DRIVER_END_LOCATION_DISTION_ERROR);
        }*/


        //计算实际里程
        BigDecimal realDistance = locationFeignClient.calculateOrderRealDistance(orderFeeForm.getOrderId()).getData();
        //计算总费用
        FeeRuleRequestForm feeRuleRequestForm=new FeeRuleRequestForm();
        feeRuleRequestForm.setDistance(realDistance);
        Integer waitMinute=(int)(orderInfo.getArriveTime().getTime()-orderInfo.getStartServiceTime().getTime())/1000/60;
        feeRuleRequestForm.setWaitMinute(waitMinute);
        feeRuleRequestForm.setStartTime(orderInfo.getStartServiceTime());
        FeeRuleResponseVo feeRuleResponseVo = feeRuleFeignClient.calculateOrderFee(feeRuleRequestForm).getData();

        BigDecimal totalAmount=feeRuleResponseVo.getTotalAmount().add(orderFeeForm.getTollFee())
                .add(orderFeeForm.getParkingFee()).add(orderFeeForm.getOtherFee())
                .add(orderInfo.getFavourFee());
        //计算哦平台奖励
        String startTime = new DateTime(orderInfo.getStartServiceTime()).toString("yyyy-MM-dd") + " 00:00:00";
        String endTime = new DateTime(orderInfo.getStartServiceTime()).toString("yyyy-MM-dd") + " 24:00:00";
        Long orderNum = orderInfoFeignClient.getOrderNumByTime(startTime, endTime).getData();
        //4.2.封装参数
        RewardRuleRequestForm rewardRuleRequestForm = new RewardRuleRequestForm();
        rewardRuleRequestForm.setStartTime(orderInfo.getStartServiceTime());
        rewardRuleRequestForm.setOrderNum(orderNum);
        //4.3.执行
        RewardRuleResponseVo rewardRuleResponseVo = rewardRuleFeignClient.calculateOrderRewardFee(rewardRuleRequestForm).getData();
        // 计算分账信息
        ProfitsharingRuleRequestForm profitsharingRuleRequestForm = new ProfitsharingRuleRequestForm();
        profitsharingRuleRequestForm.setOrderAmount(feeRuleResponseVo.getTotalAmount());
        profitsharingRuleRequestForm.setOrderNum(orderNum);
        ProfitsharingRuleResponseVo profitsharingRuleResponseVo = profitsharingRuleFeignClient.calculateOrderProfitsharingFee(profitsharingRuleRequestForm).getData();
        //封装实体类，结束代驾，添加信息到数据库
        UpdateOrderBillForm updateOrderBillForm = new UpdateOrderBillForm();
        updateOrderBillForm.setOrderId(orderFeeForm.getOrderId());
        updateOrderBillForm.setDriverId(orderFeeForm.getDriverId());
        //路桥费、停车费、其他费用
        updateOrderBillForm.setTollFee(orderFeeForm.getTollFee());
        updateOrderBillForm.setParkingFee(orderFeeForm.getParkingFee());
        updateOrderBillForm.setOtherFee(orderFeeForm.getOtherFee());
        //乘客好处费
        updateOrderBillForm.setFavourFee(orderInfo.getFavourFee());

        //实际里程
        updateOrderBillForm.setRealDistance(realDistance);
        //订单奖励信息
        BeanUtils.copyProperties(rewardRuleResponseVo, updateOrderBillForm);
        //代驾费用信息
        BeanUtils.copyProperties(feeRuleResponseVo, updateOrderBillForm);

        //分账相关信息
        BeanUtils.copyProperties(profitsharingRuleResponseVo, updateOrderBillForm);
        updateOrderBillForm.setProfitsharingRuleId(profitsharingRuleResponseVo.getProfitsharingRuleId());
        log.info("结束代驾，更新账单信息：{}", JSON.toJSONString(updateOrderBillForm));

        //7.结束代驾更新账单
        orderInfoFeignClient.endDrive(updateOrderBillForm);
        return true;
    }
    @Override
    public Boolean endDriveByThread(OrderFeeForm orderFeeForm) {
        /*CompletableFuture.supplyAsync(()->{OrderInfo orderInfo = orderInfoFeignClient.getOrderInfo(orderFeeForm.getOrderId()).getData();
            if(orderInfo.getDriverId()!=orderFeeForm.getDriverId()){
                throw new CException(ResultCodeEnum.ILLEGAL_REQUEST);
            },threadPoolExecutor})*/
        //根据订单id判断是否是司机接单
        OrderInfo orderInfo = orderInfoFeignClient.getOrderInfo(orderFeeForm.getOrderId()).getData();
        if(orderInfo.getDriverId()!=orderFeeForm.getDriverId()){
            throw new CException(ResultCodeEnum.ILLEGAL_REQUEST);
        }

        //计算实际里程
        BigDecimal realDistance = locationFeignClient.calculateOrderRealDistance(orderFeeForm.getOrderId()).getData();
        //计算总费用
        FeeRuleRequestForm feeRuleRequestForm=new FeeRuleRequestForm();
        feeRuleRequestForm.setDistance(realDistance);
        Integer waitMinute=(int)(orderInfo.getArriveTime().getTime()-orderInfo.getStartServiceTime().getTime())/1000/60;
        feeRuleRequestForm.setWaitMinute(waitMinute);
        feeRuleRequestForm.setStartTime(orderInfo.getStartServiceTime());
        FeeRuleResponseVo feeRuleResponseVo = feeRuleFeignClient.calculateOrderFee(feeRuleRequestForm).getData();

        BigDecimal totalAmount=feeRuleResponseVo.getTotalAmount().add(orderFeeForm.getTollFee())
                .add(orderFeeForm.getParkingFee()).add(orderFeeForm.getOtherFee())
                .add(orderInfo.getFavourFee());
        //计算哦平台奖励
        String startTime = new DateTime(orderInfo.getStartServiceTime()).toString("yyyy-MM-dd") + " 00:00:00";
        String endTime = new DateTime(orderInfo.getStartServiceTime()).toString("yyyy-MM-dd") + " 24:00:00";
        Long orderNum = orderInfoFeignClient.getOrderNumByTime(startTime, endTime).getData();
        //4.2.封装参数
        RewardRuleRequestForm rewardRuleRequestForm = new RewardRuleRequestForm();
        rewardRuleRequestForm.setStartTime(orderInfo.getStartServiceTime());
        rewardRuleRequestForm.setOrderNum(orderNum);
        //4.3.执行
        RewardRuleResponseVo rewardRuleResponseVo = rewardRuleFeignClient.calculateOrderRewardFee(rewardRuleRequestForm).getData();
        // 计算分账信息
        ProfitsharingRuleRequestForm profitsharingRuleRequestForm = new ProfitsharingRuleRequestForm();
        profitsharingRuleRequestForm.setOrderAmount(feeRuleResponseVo.getTotalAmount());
        profitsharingRuleRequestForm.setOrderNum(orderNum);
        ProfitsharingRuleResponseVo profitsharingRuleResponseVo = profitsharingRuleFeignClient.calculateOrderProfitsharingFee(profitsharingRuleRequestForm).getData();
        //封装实体类，结束代驾，添加信息到数据库
        UpdateOrderBillForm updateOrderBillForm = new UpdateOrderBillForm();
        updateOrderBillForm.setOrderId(orderFeeForm.getOrderId());
        updateOrderBillForm.setDriverId(orderFeeForm.getDriverId());
        //路桥费、停车费、其他费用
        updateOrderBillForm.setTollFee(orderFeeForm.getTollFee());
        updateOrderBillForm.setParkingFee(orderFeeForm.getParkingFee());
        updateOrderBillForm.setOtherFee(orderFeeForm.getOtherFee());
        //乘客好处费
        updateOrderBillForm.setFavourFee(orderInfo.getFavourFee());

        //实际里程
        updateOrderBillForm.setRealDistance(realDistance);
        //订单奖励信息
        BeanUtils.copyProperties(rewardRuleResponseVo, updateOrderBillForm);
        //代驾费用信息
        BeanUtils.copyProperties(feeRuleResponseVo, updateOrderBillForm);

        //分账相关信息
        BeanUtils.copyProperties(profitsharingRuleResponseVo, updateOrderBillForm);
        updateOrderBillForm.setProfitsharingRuleId(profitsharingRuleResponseVo.getProfitsharingRuleId());
        log.info("结束代驾，更新账单信息：{}", JSON.toJSONString(updateOrderBillForm));

        //7.结束代驾更新账单
        orderInfoFeignClient.endDrive(updateOrderBillForm);
        return true;
    }

    @Override
    public Boolean sendOrderBillInfo(Long orderId, Long driverId) {
        return orderInfoFeignClient.sendOrderBillInfo(orderId, driverId).getData();
    }

    @Override
    public PageVo findDriverOrderPage(Long driverId, Long page, Long limit) {
        return orderInfoFeignClient.findDriverOrderPage(driverId, page, limit).getData();
    }
}
